package com.ipay.wechat.service.impl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.ipay.foreign.pojo.MerchantPayParameter;
import com.ipay.foreign.service.MerchantPayParameterService;
import com.ipay.service.ApiPabcsService;
import com.ipay.service.ApiPayService;
import com.ipay.utils.Constant;
import com.ipay.utils.IPUtils;
import com.ipay.utils.R;
import com.ipay.utils.StringUtil;
import com.ipay.wechat.component.Wechat;
import com.ipay.wechat.dao.TPayresultDao;
import com.ipay.wechat.pojo.PayChannelEntity;
import com.ipay.wechat.pojo.TOrderpayinfoEntity;
import com.ipay.wechat.pojo.TPayresultEntity;
import com.ipay.wechat.service.TOrderpayinfoService;
import com.ipay.wechat.util.Utils;
import net.sf.json.JSONArray;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ipay.wechat.dao.PayorderDao;
import com.ipay.wechat.pojo.PayorderEntity;
import com.ipay.wechat.service.PayorderService;
import org.springframework.transaction.annotation.Transactional;

@Service("payorderService")
public class PayorderServiceImpl implements PayorderService {
	private Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
	private PayorderDao payorderDao;
	@Autowired
	private TPayresultDao resultDao;
	@Autowired
	private Wechat wechat;
	@Autowired
	private ApiPayService apiPayService;
	@Autowired
	private ApiPabcsService apiPabcsService;
	@Autowired
	private TOrderpayinfoService payinfoService;
	@Autowired
	private MerchantPayParameterService merchantPayParameterService;


	@Override
	public PayorderEntity queryObject(String id) {
		return payorderDao.queryObject(id);
	}

	@Override
	public List<PayorderEntity> queryList(Map<String, Object> map) {
		return payorderDao.queryList(map);
	}

	@Override
	public int queryTotal(Map<String, Object> map) {
		return payorderDao.queryTotal(map);
	}

	@Override
	public void save(PayorderEntity payorder) {
		payorderDao.save(payorder);
	}


	/**
	 * 订单生成处理====公众号支付
	 * @param payorder
	 * @param payChannel
	 * @return
	 */
	@Override
	@Transactional
	public R paylist(PayorderEntity payorder,PayChannelEntity payChannel) {
		Map<String, Object> dataMap=new HashMap<String,Object>();
		dataMap.put("pmt_type","2");
		JSONArray datajson = JSONArray.fromObject(dataMap);
		///open_id=87f46f5db1b65f0ac195285f49ee6958&timestamp=1497957842&data=3304A5EC2CDEB4D12ED3338B5C01BF6B
		String postUrl = "http://openapi.tlinx.cn/mct1/paylist";//http://openapi.tlinx.cn/mct1
		Map<String, Object> mapp = apiPabcsService.pabcsPayPost(payChannel.getPayKey(),payChannel.getPayChannelNo(),datajson.toString(),postUrl);
		return R.ok();
	}

	/**
	 * 订单生成处理====公众号支付
	 * @param payorder
	 * @param payChannel
	 * @return
	 */
	@Override
	@Transactional
	public R savePayOrder(PayorderEntity payorder,PayChannelEntity payChannel) {
		///修改第三方支付状态  参数表里的状态
		if(StringUtil.isNotEmpty(payorder.getLaunchMode())&&Constant.LAUNCHMODE_DSF_PC.equals(payorder.getLaunchMode())) {
			MerchantPayParameter merchantPayParameter = new MerchantPayParameter();
			merchantPayParameter.setStart(Constant.START_ZFZ);//发起 订单状态（0未支付，1支付中，2已支付，3已取消）
			merchantPayParameter.setId(Long.valueOf(payorder.getPayId()));
			merchantPayParameterService.update(merchantPayParameter);
		}
		payorderDao.save(payorder);
		Map<String, String> map = new HashMap<String, String>();
		if (payorder.getResource() != null && payorder.getResource().equals("0")) {//获取：来源（0 微信、1 支付宝） // 微信支付
			logger.info("微信-----====" + payorder.getMchCreateIp());//113.246.93.135, 14.17.37.144
			String iscreditCard = String.valueOf(payChannel.getIscreditCard());////是否支持 信用卡支付， 1 否   0 是
			map = wxPayInit(payorder, iscreditCard);
		} else if (payorder.getResource() != null && payorder.getResource().equals("1")) { // 支付宝支付
			logger.info("支付宝-----====" + payorder.getMchCreateIp());
			map = aliPayInit(payorder);
		} else if (payorder.getResource() != null && payorder.getResource().equals("9")) {  ///统一刷卡支付
			logger.info("统一刷卡支付-----====" + payorder.getMchCreateIp());
			map = cardPayInit(payorder);
		} else {
			return R.error("支付来源错误");
		}
		map.put("mch_id", payChannel.getPayChannelNo());//商户编号
		Map<String, Object> mapp = apiPayService.wxJsPay(map, payChannel.getPayKey());
		if (mapp != null && mapp.get("code").toString().equals("0")) {
			logger.info("payinfo-----====" + mapp.get("code"));
			if (mapp.get("pay_info") != null) {
				logger.info("payinfo-----====" + mapp.get("pay_info"));
				//支付返回结果保存
				TOrderpayinfoEntity payinfo = new TOrderpayinfoEntity();
				payinfo.setOrderno(payorder.getRecordno());
				payinfo.setPayinfo(mapp.get("pay_info").toString());
				payinfoService.save(payinfo);

				payorder.setStatus(Constant.STATUS_PROCESSING);
				payorderDao.update(payorder);

				if (payorder.getResource() != null && payorder.getResource().equals("0")) {
					// 微信支付
					String token_id = mapp.get("token_id").toString();
					logger.info("-----token_id------" + token_id + "-----pay_info------" + JSON.parseObject(mapp.get("pay_info").toString(), Map.class));
					return R.ok().put("token_id", token_id).put("payInfo",
							JSON.parseObject(mapp.get("pay_info").toString(), Map.class));
				} else {
					logger.info("alipayinfo-----" + mapp.get("pay_info"));
					Map<String, String> alimap = JSON.parseObject(mapp.get("pay_info").toString(), Map.class);
					String tradeNO = alimap.get("tradeNO").toString();
					return R.ok().put("tradeNO", tradeNO).put("payUrl", mapp.get("pay_url"));
				}
			} else {// 异常记录
				payorder.setRemark("支付异常");
				payorder.setStatus(Constant.STATUS_ERROR);
				payorderDao.update(payorder);
				return R.error(payorder.getRemark());
			}
		}else{
			// 异常记录
			if(mapp != null && StringUtil.isNotEmpty(mapp.get("msg"))){
				payorder.setRemark(mapp.get("msg").toString());
			}
			payorderDao.update(payorder);
			return R.error(payorder.getRemark());
		}
	}


	/**
	 * 订单生成处理=====扫码支付
	 * @param payorder
	 * @param payChannel
	 * @return
	 */
	@Override
	@Transactional
	public R savePayNativeOrder(PayorderEntity payorder,PayChannelEntity payChannel) {
		payorderDao.save(payorder);
		Map<String, String> map = new HashMap<String, String>();
		if (payorder.getResource() != null && payorder.getResource().equals("0")) {//获取：来源（0 微信、1 支付宝） // 微信支付
			logger.info("微信-----====" + payorder.getMchCreateIp());//113.246.93.135, 14.17.37.144
			String iscreditCard = String.valueOf(payChannel.getIscreditCard());////是否支持 信用卡支付， 1 否   0 是
			map = wxPayInit(payorder, iscreditCard);
		} else if (payorder.getResource() != null && payorder.getResource().equals("1")) { // 支付宝支付
			logger.info("支付宝-----====" + payorder.getMchCreateIp());
			map = aliPayInit(payorder);
		} else if (payorder.getResource() != null && payorder.getResource().equals("9")) {  ///统一刷卡支付
			logger.info("统一刷卡支付-----====" + payorder.getMchCreateIp());
			map = cardPayInit(payorder);
		} else {
			return R.error("支付来源错误");
		}
		map.put("mch_id", payChannel.getPayChannelNo());//商户编号
		Map<String, Object> mapp = apiPayService.wxJsPay(map, payChannel.getPayKey());

		if (mapp != null && mapp.get("code").toString().equals("0")) {
			logger.info("payinfo-----====" + mapp.get("code"));
			if (mapp.get("pay_info") != null) {
				logger.info("payinfo-----====" + mapp.get("pay_info"));
				//支付返回结果保存
				TOrderpayinfoEntity payinfo = new TOrderpayinfoEntity();
				payinfo.setOrderno(payorder.getRecordno());
				payinfo.setPayinfo(mapp.get("pay_info").toString());
				payinfoService.save(payinfo);

				payorder.setStatus(Constant.STATUS_PROCESSING);
				payorderDao.update(payorder);

				if (payorder.getResource() != null && payorder.getResource().equals("0")) {
					// 微信支付
					String token_id = mapp.get("token_id").toString();
					logger.info("-----token_id------" + token_id + "-----pay_info------" + JSON.parseObject(mapp.get("pay_info").toString(), Map.class));
					return R.ok().put("token_id", token_id).put("payInfo",
							JSON.parseObject(mapp.get("pay_info").toString(), Map.class));
				} else {
					logger.info("alipayinfo-----" + mapp.get("pay_info"));
					Map<String, String> alimap = JSON.parseObject(mapp.get("pay_info").toString(), Map.class);
					String tradeNO = alimap.get("tradeNO").toString();
					return R.ok().put("tradeNO", tradeNO).put("payUrl", mapp.get("pay_url"));
				}
			} else {// 异常记录
				payorder.setRemark("支付异常");
				payorder.setStatus(Constant.STATUS_ERROR);
				payorderDao.update(payorder);
				return R.error(payorder.getRemark());
			}
		}else{
			// 异常记录
			if(mapp != null&&StringUtil.isNotEmpty(mapp.get("msg"))){
				payorder.setRemark(mapp.get("msg").toString());
			}
			payorderDao.update(payorder);
			return R.error(payorder.getRemark());
		}
	}

	/**
	 * //修改退款订单状态
	 * @param payorder
	 */
	@Override
	public void update(PayorderEntity payorder) {
		payorderDao.update(payorder);
	}

	@Override
	@Transactional
	public void update(PayorderEntity payorder,TPayresultEntity entity ) {
		if(StringUtil.isNotEmpty(entity.getOutTradeNo())){
			resultDao.save(entity);
		}
		payorderDao.update(payorder);

		if(StringUtil.isNotEmpty(payorder.getLaunchMode())&&Constant.LAUNCHMODE_DSF_PC.equals(payorder.getLaunchMode())) {
			MerchantPayParameter merchantPayParameter = new MerchantPayParameter();
			merchantPayParameter.setStart(Constant.START_YZF);//发起 订单状态（0未支付，1支付中，2已支付，3已取消）
			merchantPayParameter.setSponsorOrderNo(payorder.getSponsorOrderNo());
			merchantPayParameterService.update(merchantPayParameter);
		}
	}

	@Override
	public void delete(String id) {
		payorderDao.delete(id);
	}

	@Override
	public void deleteBatch(String[] ids) {
		payorderDao.deleteBatch(ids);
	}

	@Override
	public PayorderEntity queryByOderNo(String orderNo) {
		return payorderDao.queryByOderNo(orderNo);
	}

	@Override
	public PayorderEntity queryByRelationOrder(String orderNo) {
		// 支付订单
		PayorderEntity payOrder = payorderDao.queryByOderNo(orderNo);
		return payorderDao.queryByRelationOrder(payOrder.getId());
	}
	/**
	 * 修改订单状态专用（定时器块）
	 * @param payorder
	 * @return
	 */
	@Override
	public void updateRefundStart(PayorderEntity payorder) {
		payorderDao.updateRefundStart(payorder);
	}

	@Override
	public BigDecimal findTdSumAmountByPayChannelId(Map<String, Object> map) {
		return payorderDao.findTdSumAmountByPayChannelId(map);
	}



	/**
	 * 组装微信支付提交参数
	 * @param payorder
	 * @return
	 */
	private Map<String, String> wxPayInit(PayorderEntity payorder, String iscreditCard) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("service", "pay.weixin.jspay");
		map.put("version", "1.1");
		map.put("charset", "UTF-8");
		map.put("sign_type", "MD5");
		map.put("is_raw", "1");
		map.put("sub_appid", wechat.getAppId());
		map.put("sub_openid", payorder.getOpenid());//正式环境启用
		map.put("notify_url", wechat.getBaseUrlHttp()+ "payorder/jspayNotify");//Constant.DOMAINURL_HTTP
		//map.put("callback_url", wechat.getBaseUrl() + "pay/pay_success.html");//Constant.DOMAINURL_HTTPS
		map.put("callback_url", wechat.getBaseUrlWechat() + "pay_success.html");//Constant.DOMAINURL_HTTPS
		map.put("nonce_str", String.valueOf(System.currentTimeMillis()));
		map.put("out_trade_no", payorder.getRecordno());//商户订单号
		map.put("limit_credit_pay", iscreditCard);
		map.put("body", payorder.getBody());
		BigDecimal totalFee = payorder.getAmount().multiply(BigDecimal.valueOf(100));
		map.put("total_fee", Utils.round(totalFee, 0).toString());
		map.put("mch_create_ip", payorder.getMchCreateIp());
		return map;
	}

	/**
	 * 组装支付宝支付提交参数
	 * @param payorder
	 * @return
	 */
	private Map<String, String> aliPayInit(PayorderEntity payorder) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("service", "pay.alipay.jspay");
		map.put("charset", "UTF-8");
		map.put("sign_type", "MD5");
		map.put("sub_openid", payorder.getOpenid());//正式环境启用
		map.put("notify_url", wechat.getBaseUrlHttp() + "payorder/jspayNotify");//Constant.DOMAINURL_HTTP
		map.put("nonce_str", String.valueOf(System.currentTimeMillis()));
		map.put("out_trade_no", payorder.getRecordno());
		map.put("buyer_id", payorder.getOpenid());
		map.put("body", payorder.getBody());
		BigDecimal totalFee = payorder.getAmount().multiply(BigDecimal.valueOf(100));
		map.put("total_fee", Utils.round(totalFee, 0).toString());
		map.put("mch_create_ip", payorder.getMchCreateIp());
		return map;
	}

	/**
	 * 组装统一刷卡支付
	 * @param payorder
	 * @return
	 * 7
	 */
	private Map<String, String> cardPayInit(PayorderEntity payorder) {
		Map<String, String> map = new HashMap<String, String>();
		map.put("service", "unified.trade.micropay");
		map.put("version", "2.0");  //--
		map.put("charset", "UTF-8");//--
		map.put("sign_type", "MD5");//--
		map.put("out_trade_no", payorder.getRecordno());
		map.put("device_info", payorder.getCodeNo());//终端设备号，商户自定义。特别说明：对于QQ钱包支付，此参数必传，否则会报错。
		map.put("body", payorder.getBody());
		BigDecimal totalFee = payorder.getAmount().multiply(BigDecimal.valueOf(100));
		map.put("total_fee", Utils.round(totalFee, 0).toString());
		map.put("mch_create_ip", payorder.getMchCreateIp());
		map.put("auth_code", payorder.getAuthCode());//--//扫码支付授权码， 设备读取用户展示的条码或者二维码信息
		map.put("nonce_str", String.valueOf(System.currentTimeMillis()));
		return map;
	}
}
